|
(*~\Глагол\Отделы\Числа~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**) ОТДЕЛ Текст;
(*============================================================================*
* НАЗНАЧЕНИЕ: преобразование Чисел в(из) Текст(а)
*----------------------------------------------------------------------------*
* В задачах <ИзЧЦел> и <ИзЧВещ> входное <описание> - это цепочка знаков,
* содержащая и обычные знаки, которые просто переписываются в <текст>
* и описатели представлений чисел, которые имеют следующее строение:
*
* %[<номарг>:,-,<ширина>,.<точность>]<вид>
*
* Описатель представления начинается со знака '%'. Затем без
* пробелов следует ряд [необязательных] параметров:
*
* [<номарг>:] - определяет номер аргумента, к которому относится
* данный описатель
* [-] - признак выравнивания влево
* [<ширина>] - ширина поля вывода
* [.<точность>] - параметр точности
* <вид> - знак, определяющий вид текущего аргумента
*
* Знаки, определяющие вид аргумента:
*
* 'd'-Десятичное целое. Значение аргумента преобразуется в цепочку
* десятичных цифр. Если описатель представления содержит параметр
* точности, то текст должен содержать количество цифр, не
* менее указанного значения. Если значение содержит меньше
* цифр, то оно дополняется слева нулями.
*
* 'x'-Шестнадцатеричное целое. Значение аргумента преобразуется в цепочку
* шестнадцатеричных цифр. Если описатель представления содержит
* параметр точности, то текст должен содержать количество цифр, не
* менее указанного значения. Если значение содержит меньше
* цифр, то оно дополняется слева нулями.
*
* 'e'-Вещественное число в научном представлении.
* Значение преобразуется в цепочку вида "-ц,цц...E+ццц", где ц
* обозначает цифру. Отрицательные числа начинаются со знака минус.
* Перед десятичной запятой всегда имеется одна цифра. Общее
* число цифр (включая цифру до запятой) задается параметром точности.
* По умолчанию точность равна 15.
* После знака порядка "E" всегда присутствует знак плюс или
* минус и 3 цифры порядка.
*
* 'f'-Вещественное число с неподвижной запятой.
* Значение преобразуется в цепочку вида "-ццц,ццц...".
* Отрицательные числа начинаются со знака минус.
* Параметр точности показывает, сколько цифр будет после запятой.
* По умолчанию точность равна 2.
*
* 'g'-Вещественное число в общем виде.
* Значение преобразуется в кратчайшее десятичное представление
* (научное или неподвижное). По умолчанию число цифр, которое задается
* параметром точности, равно 15. Лишние нули удаляются, а запятая
* появляется только при необходимости. Результирующая цепочка
* представляется с неподвижной запятой, если число цифр левее запятой
* меньше или равно указанной точности и если значение больше
* или равно 0,00001. Иначе цепочка будет представлена в научном
* представлении.
*
* 'c'-Знак. Значение аргумента преобразуется в знак с порядковым
* номером, равным значению аргумента.
*
* Если <вид> не принадлежит {'d','x','c','e','f','g'}, то параметры
* применяются не к аргументу, а к знаку <вид>.
* Числовые параметры могут извлекаться из текущего аргумента,
* если в качестве параметра выступает знак '*'.
* Знак 't' обозначает отсуп заданной ширины. По умолчанию ширина = 8.
*============================================================================*)
ИСПОЛЬЗУЕТ
<*ЕСЛИ НЕ ЗАДАНО("МПГ") ТО*>
Асм ИЗ "..\Иное\",
<*КОН*>
Буква ИЗ "..\Иное\",
Знак ИЗ "..\Иное\",
Цепь ИЗ "..\Иное\";
ВИД
Число-=ЦЕПЬ[32];
ВИД
РядЧВещ=РЯД 4 ИЗ ШИРВЕЩ;
РядЧЦел=РЯД 4 ИЗ ШИРЦЕЛ;
<*ЕСЛИ НЕ ЗАДАНО("МПГ") ТО*>
(******************************************************************************)
ЗАДАЧА Особенность(число:ШИРВЕЩ; текст+:Число; дл+:ЦЕЛ):КЛЮЧ;
(* Определяет и обозначает особые состояние <число>
******************************************************************************
* Ответ: ВКЛ, если <число> - не является числом *)
ПОСТ
ПлюсБеск = "+БЕСК";
МинусБеск = "-БЕСК";
НеЧисло = "НЕЧ";
УКАЗ
ВЫБРАТЬ Асм.Особенность(число) ИЗ
| Асм.МинусБеск:
текст:=МинусБеск;
дл:=ДЛИНА(МинусБеск)
| Асм.ПлюсБеск:
текст:=ПлюсБеск;
дл:=ДЛИНА(ПлюсБеск)
| Асм.НеЧисло:
текст:=НеЧисло;
дл:=ДЛИНА(НеЧисло)
ИНАЧЕ
ВОЗВРАТ ОТКЛ
КОН;
ВОЗВРАТ ВКЛ
КОН Особенность;
(******************************************************************************)
ЗАДАЧА ИзВещЕ-(число:ШИРВЕЩ; точность:ЦЕЛ; текст+:Число; дл+:ЦЕЛ);
(* Вещественное число в научном представлении.
******************************************************************************
* До: <число> - преобразуемое число
* <точность> - цифр после запятой
* После: <текст> - текстовое представление числа
* <дл> - его длина *)
ПЕР
порядок:ЦЕЛ; (* порядок числа *)
цифры:Число; (* цифры без точки *)
пц:ЦЕЛ; (* позиция цифры *)
УКАЗ
ЕСЛИ Особенность(число,текст,дл) ТО
ВОЗВРАТ
КОН;
ЕСЛИ точность < 0 ТО
точность:=15
АЕСЛИ точность > 18 ТО
точность:=18
КОН;
дл:=0;
ЕСЛИ число < 0 ТО (* знак перед числом *)
текст[дл]:='-';
УВЕЛИЧИТЬ(дл)
КОН;
число:=МОДУЛЬ(число);
порядок:=Асм.Порядок(число);
Асм.ВЦифры(число,точность+1,цифры); (* 18 цифр *)
ЕСЛИ цифры[0] = '0' ТО
пц:=1
ИНАЧЕ (* есть десятки *)
пц:=0;
УВЕЛИЧИТЬ(порядок)
КОН;
текст[дл]:=цифры[пц]; (* до запятой *)
УВЕЛИЧИТЬ(дл); УВЕЛИЧИТЬ(пц);
текст[дл]:=','; (* запятая *)
УВЕЛИЧИТЬ(дл);
ПОКА точность > 0 ВЫП (* после запятой *)
текст[дл]:=цифры[пц];
УВЕЛИЧИТЬ(дл); УВЕЛИЧИТЬ(пц);
УМЕНЬШИТЬ(точность)
КОН;
текст[дл]:='E'; (* E *)
УВЕЛИЧИТЬ(дл);
ЕСЛИ порядок < 0 ТО (* знак порядка *)
текст[дл]:='-';
порядок:=-порядок
ИНАЧЕ
текст[дл]:='+'
КОН;
пц:=дл+3;
ПОКА пц > дл ВЫП (* порядок *)
текст[пц]:=ВЗНАК(48+(порядок ОСТАТОК 10));
порядок:=порядок ДЕЛИТЬ 10;
УМЕНЬШИТЬ(пц)
КОН;
УВЕЛИЧИТЬ(дл,4);
текст[дл]:=0X
КОН ИзВещЕ;
(******************************************************************************)
ЗАДАЧА ИзВещФ-(число:ШИРВЕЩ; точность:ЦЕЛ; текст+:Число; дл+:ЦЕЛ);
(* Вещественное число с неподвижной запятой.
******************************************************************************
* До: <число> - преобразуемое число
* <точность> - цифр после запятой
* После: <текст> - текстовое представление числа
* <дл> - его длина *)
ПЕР
порядок:ЦЕЛ; (* порядок числа *)
цифры:Число; (* цифры без точки *)
пц:ЦЕЛ; (* позиция цифры *)
вхчисло:ШИРВЕЩ;(* двойник <число> *)
УКАЗ
ЕСЛИ Особенность(число,текст,дл) ТО
ВОЗВРАТ
КОН;
вхчисло:=число;
ЕСЛИ точность < 0 ТО
точность:=2
КОН;
дл:=0;
ЕСЛИ число < 0 ТО (* знак перед числом *)
текст[дл]:='-';
УВЕЛИЧИТЬ(дл)
КОН;
число:=МОДУЛЬ(число);
ЕСЛИ число >= 10 ТО
порядок:=Асм.Порядок(число)+1
ИНАЧЕ
порядок:=1
КОН;
ЕСЛИ точность+порядок >= РАЗМЕР(цифры) ТО (* совсем большое число *)
ИзВещЕ(вхчисло,точность,текст,дл);
ВОЗВРАТ
КОН;
Асм.ВЦифры(число,порядок+точность,цифры);
ЕСЛИ цифры[0] = '0' ТО
пц:=1
ИНАЧЕ (* есть десятки *)
пц:=0;
УВЕЛИЧИТЬ(порядок)
КОН;
ПОКА порядок > 0 ВЫП (* до запятой *)
текст[дл]:=цифры[пц];
УВЕЛИЧИТЬ(дл); УВЕЛИЧИТЬ(пц);
УМЕНЬШИТЬ(порядок)
КОН;
текст[дл]:=','; (* запятая *)
УВЕЛИЧИТЬ(дл);
ПОКА точность > 0 ВЫП (* после запятой *)
текст[дл]:=цифры[пц];
УВЕЛИЧИТЬ(дл); УВЕЛИЧИТЬ(пц);
УМЕНЬШИТЬ(точность)
КОН;
текст[дл]:=0X
КОН ИзВещФ;
(******************************************************************************)
ЗАДАЧА ИзВещГ-(число:ШИРВЕЩ; точность:ЦЕЛ; текст+:Число; дл+:ЦЕЛ);
(* Вещественное число в общем виде.
******************************************************************************
* До: <число> - преобразуемое число
* <точность> - цифр после запятой
* После: <текст> - текстовое представление числа
* <дл> - его длина *)
ПЕР
порядок:ЦЕЛ; (* порядок числа *)
цифры:Число; (* цифры без точки *)
пц:ЦЕЛ; (* позиция цифры *)
вхчисло:ШИРВЕЩ;(* двойник <число> *)
модвхчисло:ШИРВЕЩ;(* двойник модуля <число> *)
УКАЗ
ЕСЛИ Особенность(число,текст,дл) ТО
ВОЗВРАТ
КОН;
вхчисло:=число;
ЕСЛИ точность < 0 ТО
точность:=15
АЕСЛИ точность > 18 ТО
точность:=18
КОН;
дл:=0;
ЕСЛИ число < 0 ТО (* знак перед числом *)
текст[дл]:='-';
УВЕЛИЧИТЬ(дл)
КОН;
число:=МОДУЛЬ(число);
модвхчисло:=число;
порядок:=Асм.Порядок(число);
ЕСЛИ (порядок < -5) ИЛИ (порядок >= точность) ТО
ИзВещЕ(вхчисло,точность,текст,дл);
ВОЗВРАТ
КОН;
ЕСЛИ модвхчисло < 10 ТО
порядок:=0;
число:=модвхчисло
КОН;
УВЕЛИЧИТЬ(порядок);
ЕСЛИ точность+порядок >= РАЗМЕР(цифры) ТО (* совсем большое число *)
ИзВещЕ(вхчисло,точность,текст,дл);
ВОЗВРАТ
КОН;
Асм.ВЦифры(число,порядок+точность,цифры);
ЕСЛИ цифры[0] = '0' ТО
пц:=1
ИНАЧЕ (* есть десятки *)
пц:=0;
УВЕЛИЧИТЬ(порядок)
КОН;
ПОКА порядок > 0 ВЫП (* до запятой *)
текст[дл]:=цифры[пц];
УВЕЛИЧИТЬ(дл); УВЕЛИЧИТЬ(пц);
УМЕНЬШИТЬ(порядок)
КОН;
ПОКА (точность > 0) И (цифры[пц+точность-1] = '0') ВЫП (* убираем нули *)
УМЕНЬШИТЬ(точность)
КОН;
ЕСЛИ точность > 0 ТО (* запятая *)
текст[дл]:=',';
УВЕЛИЧИТЬ(дл)
КОН;
ПОКА точность > 0 ВЫП (* после запятой *)
текст[дл]:=цифры[пц];
УВЕЛИЧИТЬ(дл); УВЕЛИЧИТЬ(пц);
УМЕНЬШИТЬ(точность)
КОН;
текст[дл]:=0X
КОН ИзВещГ;
<*КОН*>
(******************************************************************************)
ЗАДАЧА ЗадомНаПеред(цепь+:ЦЕПЬ; дл:ЦЕЛ);
ПЕР
поз:ЦЕЛ;
зн:ЗНАК;
УКАЗ
поз:=0;
УМЕНЬШИТЬ(дл);
ПОКА поз < дл ВЫП
зн:=цепь[поз]; цепь[поз]:=цепь[дл]; цепь[дл]:=зн;
УВЕЛИЧИТЬ(поз); УМЕНЬШИТЬ(дл)
КОН
КОН ЗадомНаПеред;
(******************************************************************************)
ЗАДАЧА ИзЦел(число:ШИРЦЕЛ; основание,нужноцифр:ЦЕЛ; текст+:Число; дл+:ЦЕЛ);
(* Преобразовать целое число в текстовое представление.
******************************************************************************
* До: <число> - преобразуемое число
* <основание> - основание системы счисления
* <нужноцифр> - нужное количество цифр результата
* После: <текст> - текстовое представление числа
* <дл> - его длина *)
ПЕР
можноцифр:ЦЕЛ; (* количество цифр, которое возможно записать в результат *)
цифра:ЦЕЛ; (* текущая цифра *)
минус:КЛЮЧ; (* ВКЛ, если число отрицательное *)
УКАЗ
дл:=0;
можноцифр:=РАЗМЕР(текст)-1;
ЕСЛИ нужноцифр > можноцифр ТО
нужноцифр:=можноцифр
КОН;
минус:=число < 0;
ЕСЛИ минус ТО
ЕСЛИ основание = 16 ТО
минус:=ОТКЛ;
ЕСЛИ нужноцифр = -1 ТО
нужноцифр:=8
КОН;
можноцифр:=16
АЕСЛИ число = МИН(ШИРЦЕЛ) ТО
текст:="-9223372036854775808";
дл:=ДЛИНА(текст);
ВОЗВРАТ
ИНАЧЕ
УМЕНЬШИТЬ(нужноцифр); (* для знака в результате *)
число:=-число
КОН
КОН;
ПОВТОРЯТЬ
цифра:=МОДУЛЬ(УЗК(число ОСТАТОК основание));
ЕСЛИ цифра < 10 ТО
текст[дл]:=ВЗНАК(48+цифра)
ИНАЧЕ
текст[дл]:=ВЗНАК(55+цифра)
КОН;
число:=число ДЕЛИТЬ основание;
УВЕЛИЧИТЬ(дл);
ЕСЛИ дл >= можноцифр ТО
число:=0
КОН
ДО ((число = 0) ИЛИ (число = -1)) И (дл >= нужноцифр);
ЕСЛИ минус ТО
текст[дл]:="-";
УВЕЛИЧИТЬ(дл)
КОН;
ЗадомНаПеред(текст,дл);
текст[дл]:=0X
КОН ИзЦел;
(******************************************************************************)
ЗАДАЧА ИзЦел10-(число:ШИРЦЕЛ; нужноцифр:ЦЕЛ; текст+:Число);
(* Преобразовать целое число в десятичное представление.
******************************************************************************
* До: <число> - преобразуемое число
* <нужноцифр> - нужное количество цифр результата
* После: <текст> - текстовое представление числа *)
ПЕР
дл:ЦЕЛ;
УКАЗ
ИзЦел(число,10,нужноцифр,текст,дл)
КОН ИзЦел10;
(******************************************************************************)
ЗАДАЧА ИзЦел16-(число:ШИРЦЕЛ; нужноцифр:ЦЕЛ; текст+:Число);
(* Преобразовать целое число в шестнадцатеричное представление.
******************************************************************************
* До: <число> - преобразуемое число
* <нужноцифр> - нужное количество цифр результата
* После: <текст> - текстовое представление числа *)
ПЕР
дл:ЦЕЛ;
УКАЗ
ИзЦел(число,16,нужноцифр,текст,дл)
КОН ИзЦел16;
(******************************************************************************)
ЗАДАЧА ИзЧЦелВещ(описание-:ЦЕПЬ; царги-:РядЧЦел; варги-:РядЧВещ; текст+:ЦЕПЬ);
(* Составить текст с 4-мя числами, используя описание текста.
******************************************************************************
* До: <описание> - цепочка знаков, которая содержит обычные знаки,
* которые просто переписываются в <текст> и описатели
* представлений чисел (см. их описание выше)
* <царги> - аргументы преобразования целого вида
* <варги> - аргументы преобразования вещественного вида
* После: <текст> - выходной текст *)
ПЕР
номарг:ЦЕЛ; (* номер текущего аргумента *)
длт,дло:ЦЕЛ; (* размер <текст> и <описание> *)
позт,позо:ЦЕЛ; (* позиции текущих знаков в <текст> и <описание> *)
зно:ЗНАК; (* знак, прочитанный из <описание> *)
ширина,точность:ЦЕЛ; (* параметры вывода *)
налево:КЛЮЧ; (* ВКЛ, если используется левое выравнивание *)
число:ЦЕЛ; (* число из <описание>, используемое для параметра вывода *)
текста:Число; (* текстовое представление текущего аргумента *)
дла:ЦЕЛ; (* размер <текста> *)
ЗАДАЧА СледАрг();
(* увеличить, если возможно, <номарг> *)
УКАЗ
ЕСЛИ номарг < 4-1 ТО
УВЕЛИЧИТЬ(номарг)
КОН
КОН СледАрг;
ЗАДАЧА ЗнакО(описание-:ЦЕПЬ);
(* читать следующий знак из <описание> *)
УКАЗ
ЕСЛИ позо >= дло ТО зно:=0X КОН;
ЕСЛИ зно = 0X ТО ВОЗВРАТ КОН;
зно:=описание[позо];
УВЕЛИЧИТЬ(позо)
КОН ЗнакО;
ЗАДАЧА ЧислоО(описание-:ЦЕПЬ; царги-:РядЧЦел);
(* читать <число> для параметра из <описание> или из текущего аргумена *)
УКАЗ
число:=0;
ЕСЛИ зно = '*' ТО
число:=УЗК(царги[номарг]);
СледАрг();
ЗнакО(описание)
ИНАЧЕ
ПОКА Знак.Цифра(зно) ВЫП
число:=10*число+ВЦЕЛ(зно)-ВЦЕЛ('0');
ЗнакО(описание)
КОН
КОН
КОН ЧислоО;
ЗАДАЧА ПараметрыО(описание-:ЦЕПЬ; царги-:РядЧЦел);
(* читать параметры <ширина>, <точность>, <налево> и <номарг> из <описание> *)
УКАЗ
(* <ширина>, <налево> и <номарг> *)
КОЛЬЦО
налево:=зно = '-';
ЕСЛИ налево ТО ЗнакО(описание) КОН;
ЧислоО(описание,царги);
ЕСЛИ зно = ':' ТО
номарг:=число;
ЗнакО(описание)
ИНАЧЕ
ВЫХОД
КОН
КОН;
ширина:=число;
(* <точность> *)
число:=-1;
ЕСЛИ зно = '.' ТО
ЗнакО(описание);
ЧислоО(описание,царги)
КОН;
точность:=число
КОН ПараметрыО;
ЗАДАЧА ЗнакТ(зн:ЗНАК; текст+:ЦЕПЬ);
(* писать <зн> в <текст> *)
УКАЗ
ЕСЛИ позт < длт ТО
текст[позт]:=зн;
УВЕЛИЧИТЬ(позт)
КОН
КОН ЗнакТ;
ЗАДАЧА ЗнакиТ(знаки-:ЦЕПЬ; дл:ЦЕЛ; текст+:ЦЕПЬ);
(* писать <дл> знаков <знаки> в <текст> *)
ПЕР
поз:ЦЕЛ;
УКАЗ
поз:=0;
ПОКА поз < дл ВЫП
ЗнакТ(знаки[поз],текст);
УВЕЛИЧИТЬ(поз)
КОН
КОН ЗнакиТ;
ЗАДАЧА ПробелыТ(кво:ЦЕЛ; текст+:ЦЕПЬ);
(* писать <кво> пробелов в <текст> *)
УКАЗ
ПОКА кво > 0 ВЫП
ЗнакТ(' ',текст);
УМЕНЬШИТЬ(кво)
КОН
КОН ПробелыТ;
УКАЗ
дло:=РАЗМЕР(описание);
длт:=РАЗМЕР(текст);
позо:=0;
позт:=0;
номарг:=0;
зно:=' ';
ПОВТОРЯТЬ
ЗнакО(описание);
ПОКА зно = '%' ВЫП
ЗнакО(описание);
ЕСЛИ зно = '%' ТО
ЗнакТ(зно,текст);
ЗнакО(описание)
ИНАЧЕ
ПараметрыО(описание,царги);
дла:=0;
ВЫБРАТЬ Буква.ВСтрочную(зно) ИЗ
| 't':
ЕСЛИ ширина = 0 ТО ширина:=8 КОН;
ПробелыТ(ширина - (позт ОСТАТОК ширина),текст);
ЗнакО(описание)
| 'd':
ИзЦел(царги[номарг],10,точность,текста,дла);
СледАрг();
ЗнакО(описание)
| 'x':
ИзЦел(царги[номарг],16,точность,текста,дла);
СледАрг();
ЗнакО(описание)
| 'e':
ИзВещЕ(варги[номарг],точность,текста,дла);
СледАрг();
ЗнакО(описание)
| 'f':
ИзВещФ(варги[номарг],точность,текста,дла);
СледАрг();
ЗнакО(описание)
| 'g':
ИзВещГ(варги[номарг],точность,текста,дла);
СледАрг();
ЗнакО(описание)
| 'c':
ЕСЛИ (царги[номарг] >= ВЦЕЛ(МИН(ЗНАК)))
И (царги[номарг] <= ВЦЕЛ(МАКС(ЗНАК)))
ТО
текста[0]:=ВЗНАК(царги[номарг])
ИНАЧЕ
текста:="?"
КОН;
дла:=1;
СледАрг();
ЗнакО(описание)
| 0X,'%': (* ничего не делаем *)
ИНАЧЕ
текста[0]:=зно;
дла:=1;
УВЕЛИЧИТЬ(ширина);
ЗнакО(описание)
КОН;
ЕСЛИ НЕ налево ТО ПробелыТ(ширина-дла,текст) КОН;
ЗнакиТ(текста,дла,текст);
ЕСЛИ налево ТО ПробелыТ(ширина-дла,текст) КОН;
КОН
КОН;
ЗнакТ(зно,текст)
ДО зно = 0X
КОН ИзЧЦелВещ;
(******************************************************************************)
ЗАДАЧА ИзЧЦел-(описание-:ЦЕПЬ; а0,а1,а2,а3:ШИРЦЕЛ; текст+:ЦЕПЬ);
(* Составить текст с 4-мя целыми числами, используя описание текста.
******************************************************************************
* До: <описание> - см. ИзЧЦелВещ()
* < а0 >,,< а4 > - аргументы преобразования
* После: <текст> - выходной текст *)
ПЕР
царги:РядЧЦел; (* значения аргументов а0,...,а3 в целом виде *)
варги:РядЧВещ; (* значения аргументов а0,...,а3 в вещественном виде *)
УКАЗ
царги[0]:=а0;
царги[1]:=а1;
царги[2]:=а2;
царги[3]:=а3;
варги[0]:=а0;
варги[1]:=а1;
варги[2]:=а2;
варги[3]:=а3;
ИзЧЦелВещ(описание,царги,варги,текст);
КОН ИзЧЦел;
(******************************************************************************)
ЗАДАЧА ВШирЦел0(в:ШИРВЕЩ):ШИРЦЕЛ;
УКАЗ
ЕСЛИ (в >= МИН(ШИРЦЕЛ)) И (в <= МАКС(ШИРЦЕЛ)) ТО
ВОЗВРАТ ВШИРЦЕЛ(в)
КОН;
ВОЗВРАТ 0
КОН ВШирЦел0;
(******************************************************************************)
ЗАДАЧА ИзЧВещ-(описание-:ЦЕПЬ; а0,а1,а2,а3:ШИРВЕЩ; текст+:ЦЕПЬ);
(* Составить текст с 4-мя вещественными числами, используя описание текста.
******************************************************************************
* До: <описание> - см. ИзЧЦелВещ()
* < а0 >,,< а4 > - аргументы преобразования
* После: <текст> - выходной текст *)
ПЕР
царги:РядЧЦел; (* значения аргументов а0,...,а3 в целом виде *)
варги:РядЧВещ; (* значения аргументов а0,...,а3 в вещественном виде *)
УКАЗ
царги[0]:=ВШирЦел0(а0);
царги[1]:=ВШирЦел0(а1);
царги[2]:=ВШирЦел0(а2);
царги[3]:=ВШирЦел0(а3);
варги[0]:=а0;
варги[1]:=а1;
варги[2]:=а2;
варги[3]:=а3;
ИзЧЦелВещ(описание,царги,варги,текст);
КОН ИзЧВещ;
(******************************************************************************)
ЗАДАЧА ВЦелое-(цепь-:ЦЕПЬ; поз+:ЦЕЛ; цОтвет+:ШИРЦЕЛ; вОтвет+:ШИРВЕЩ):КЛЮЧ;
(* Считывает из <цепь> начиная с позиции <поз> знаковое представление числа.
* Если это представление целого числа, то возвращает ВКЛ и записывает
* значение числа в <цОтвет>, иначе возвращает ОТКЛ, а значение записывает
* в <вОтвет>.
* По окончании <поз> указывает на следующий за числом знак. *)
ПЕР
i,m,n,d,эксп:ЦЕЛ;
мант:ШИРВЕЩ;
цифры:ЦЕПЬ[64];
знакМант,знакЭксп:ЦЕЛ;
знак:ЗНАК;
ошибка:КЛЮЧ;
длина:ЦЕЛ;
(******************************************************************************)
ЗАДАЧА ЧитатьЗнак;
(* Читает следующий <знак> из <цепь> *)
УКАЗ
ЕСЛИ поз >= длина ТО
знак:=0X
ИНАЧЕ
УВЕЛИЧИТЬ(поз);
знак:=цепь[поз]
КОН
КОН ЧитатьЗнак;
(******************************************************************************)
ЗАДАЧА ДесятьВ(x:ЦЕЛ):ШИРВЕЩ;
(* 10 в степени *)
ПЕР
ответ,множитель:ШИРВЕЩ;
УКАЗ
ответ:=1;
множитель:=10;
ПОКА x > 0 ВЫП
ЕСЛИ НЕ ЧЕТ(x) ТО ответ:=ответ*множитель КОН;
x:=x ДЕЛИТЬ 2;
ЕСЛИ x > 0 ТО (* защита <множитель> от переполнения *)
множитель:=множитель*множитель
КОН
КОН;
ВОЗВРАТ ответ
КОН ДесятьВ;
(******************************************************************************)
ЗАДАЧА ЗнакВЦел(знак:ЗНАК; система16:КЛЮЧ):ЦЕЛ;
УКАЗ
ЕСЛИ Знак.Цифра(знак) ТО
ВОЗВРАТ ВЦЕЛ(знак)-ВЦЕЛ("0")
АЕСЛИ система16 И ("A" <= знак) И (знак <= "F") ТО
ВОЗВРАТ ВЦЕЛ(знак)-ВЦЕЛ("A")+10
ИНАЧЕ
ошибка:=ВКЛ
КОН
КОН ЗнакВЦел;
(******************************************************************************)
УКАЗ
вОтвет:=0;
цОтвет:=0;
ошибка:=ОТКЛ;
длина:=ДЛИНА(цепь);
ЕСЛИ поз >= длина ТО
(* ошибка: достигнут конец цепочки *)
ВОЗВРАТ ВКЛ
КОН;
(* <поз> соответствует уже прочтённому знаку *)
УМЕНЬШИТЬ(поз);
(* пропускаем пробелы перед первой цифрой *)
ПОВТОРЯТЬ
ЕСЛИ поз >= длина ТО
(* ошибка: достигнут конец цепочки *)
ВОЗВРАТ ВКЛ
КОН;
ЧитатьЗнак
ДО знак > " ";
знакМант:=1;
ЕСЛИ знак = "-" ТО
знакМант:=-1;
ЧитатьЗнак
АЕСЛИ знак = "+" ТО
ЧитатьЗнак
АЕСЛИ НЕ Знак.Цифра(знак) ТО
(* ошибка: не нашли числа *)
ВОЗВРАТ ВКЛ
КОН;
(* читаем мантиссу *)
i:=0; m:=0; n:=0; d:=0;
КОЛЬЦО
ЕСЛИ Знак.Цифра(знак) ИЛИ (d = 0) И ("A" <= знак) И (знак <= "F") ТО
ЕСЛИ (m > 0) ИЛИ (знак # "0") ТО (* предстоящие нули пропускаем *)
ЕСЛИ n < РАЗМЕР(цифры) ТО
цифры[n]:=знак;
УВЕЛИЧИТЬ(n)
КОН;
УВЕЛИЧИТЬ(m)
КОН;
ЧитатьЗнак;
УВЕЛИЧИТЬ(i)
АЕСЛИ знак = "," ТО
ЧитатьЗнак;
ЕСЛИ d = 0 ТО (* i > 0 *)
d:=i
ИНАЧЕ
(* ошибка: неверный знак в записи числа *)
ВОЗВРАТ ВКЛ
КОН
ИНАЧЕ
ВЫХОД
КОН
КОН; (* 0 <= n <= m <= i, 0 <= d <= i *)
ЕСЛИ d = 0 ТО (* целое *)
ЕСЛИ n = m ТО
i:=0;
ЕСЛИ (знак = "H") ИЛИ (знак = "X") ТО (* 16-тиричное *)
ЧитатьЗнак;
ЕСЛИ (n > 16) ИЛИ ((n = 16) И (цифры[0] > "7")) ТО
(* ошибка: слишком большое целое *)
ВОЗВРАТ ВКЛ
КОН;
ПОКА i < n ВЫП
цОтвет:=цОтвет*10H+ЗнакВЦел(цифры[i],ВКЛ);
ЕСЛИ ошибка ТО
(* ошибка: неверный знак в записи числа *)
ВОЗВРАТ ВКЛ
КОН;
УВЕЛИЧИТЬ(i)
КОН
ИНАЧЕ (* 10-тичное *)
ПОКА i < n ВЫП
d:=ЗнакВЦел(цифры[i],ОТКЛ);
ЕСЛИ ошибка ТО
(* ошибка: неверный знак в записи числа *)
ВОЗВРАТ ВКЛ
КОН;
УВЕЛИЧИТЬ(i);
ЕСЛИ цОтвет > (МАКС(ШИРЦЕЛ)-d) ДЕЛИТЬ 10 ТО
(* ошибка: слишком большое целое *)
ВОЗВРАТ ВКЛ
КОН;
цОтвет:=цОтвет*10+d
КОН
КОН
ИНАЧЕ
(* ошибка: очень большое число *)
ВОЗВРАТ ВКЛ
КОН;
цОтвет:=знакМант*цОтвет;
ВОЗВРАТ ВКЛ
ИНАЧЕ (* дробная часть *)
мант:=0; эксп:=0;
ПОКА n > 0 ВЫП (* 0 <= мант < 1 *)
УМЕНЬШИТЬ(n);
мант:=(ЗнакВЦел(цифры[n],ОТКЛ)+мант)/10;
ЕСЛИ ошибка ТО
(* ошибка: неверный знак в записи числа *)
ВОЗВРАТ ВКЛ
КОН
КОН;
ЕСЛИ (знак = "E") ИЛИ (знак = "D") ТО
ЧитатьЗнак;
знакЭксп:=1;
ЕСЛИ знак = "-" ТО
знакЭксп:=-1;
ЧитатьЗнак
АЕСЛИ знак = "+" ТО
ЧитатьЗнак
КОН;
ЕСЛИ Знак.Цифра(знак) ТО
ПОВТОРЯТЬ
n:=ЗнакВЦел(знак,ОТКЛ);
ЧитатьЗнак;
ЕСЛИ эксп <= (МАКС(ШИРЦЕЛ)-n) ДЕЛИТЬ 10 ТО
эксп:=эксп*10+n
ИНАЧЕ
(* ошибка: очень большое число *)
ВОЗВРАТ ВКЛ
КОН
ДО НЕ Знак.Цифра(знак);
эксп:=знакЭксп*эксп
ИНАЧЕ
(* ошибка: неверный знак в записи числа *)
ВОЗВРАТ ВКЛ
КОН
КОН;
УМЕНЬШИТЬ(эксп,i-d-m); (* сдвиг десятичной точки *)
ЕСЛИ эксп < 0 ТО
ЕСЛИ эксп <= -307 ТО
(* ошибка: очень маленькое число *)
ВОЗВРАТ ВКЛ
КОН;
вОтвет:=мант/ДесятьВ(-эксп)
ИНАЧЕ
ЕСЛИ эксп > 308 ТО
(* ошибка: очень большое число *)
ВОЗВРАТ ВКЛ
КОН;
вОтвет:=мант*ДесятьВ(эксп)
КОН
КОН;
вОтвет:=знакМант*вОтвет;
ВОЗВРАТ ОТКЛ
КОН ВЦелое;
(******************************************************************************)
ЗАДАЧА ВШирВещ-(цепь-:ЦЕПЬ; поз+:ЦЕЛ):ШИРВЕЩ;
(* Считывает из <цепь> начиная с позиции <поз> знаковое представление числа
* и переводит его в ШИРВЕЩ вид. По окончании <поз> указывает на следующий
* за числом знак *)
ПЕР
ширцел:ШИРЦЕЛ;
ширвещ:ШИРВЕЩ;
УКАЗ
ЕСЛИ ВЦелое(цепь,поз,ширцел,ширвещ) ТО
ВОЗВРАТ ширцел
ИНАЧЕ
ВОЗВРАТ ширвещ
КОН
КОН ВШирВещ;
(******************************************************************************)
ЗАДАЧА ВВещ-(цепь-:ЦЕПЬ; поз+:ЦЕЛ):ВЕЩ;
(* Считывает из <цепь> начиная с позиции <поз> знаковое представление числа
* и переводит его в ВЕЩ вид. По окончании <поз> указывает на следующий
* за числом знак *)
УКАЗ
ВОЗВРАТ УЗК(ВШирВещ(цепь,поз))
КОН ВВещ;
(******************************************************************************)
ЗАДАЧА ВШирЦел-(цепь-:ЦЕПЬ; поз+:ЦЕЛ):ШИРЦЕЛ;
(* Считывает из <цепь> начиная с позиции <поз> знаковое представление числа
* и переводит его в ШИРЦЕЛ вид. По окончании <поз> указывает на следующий
* за числом знак *)
ПЕР
ширцел:ШИРЦЕЛ;
ширвещ:ШИРВЕЩ;
УКАЗ
ЕСЛИ ВЦелое(цепь,поз,ширцел,ширвещ) ТО
ВОЗВРАТ ширцел
ИНАЧЕ
ВОЗВРАТ ВШИРЦЕЛ(ширвещ)
КОН
КОН ВШирЦел;
(******************************************************************************)
ЗАДАЧА ВЦел-(цепь-:ЦЕПЬ; поз+:ЦЕЛ):ЦЕЛ;
(* Считывает из <цепь> начиная с позиции <поз> знаковое представление числа
* и переводит его в ЦЕЛ вид. По окончании <поз> указывает
* на следующий за числом знак *)
УКАЗ
ВОЗВРАТ УЗК(ВШирЦел(цепь,поз))
КОН ВЦел;
КОН Текст.
|
|